package com.sau.pixelcart.common.interceptor;

import com.sau.pixelcart.common.context.UserContext;
import com.sau.pixelcart.common.properties.JwtProperties;
import com.sau.pixelcart.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.impl.DefaultClaims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;

/**
 * 自定义拦截器
 */
@Slf4j
@Component
@RequiredArgsConstructor
@EnableConfigurationProperties(JwtProperties.class)
public class JwtInterceptor implements HandlerInterceptor {

    private final JwtProperties jwtProperties;

    private static final List<String> ROLE_MANAGEMENT_PATHS = Arrays.asList(
            "/user/list",
            "/user/delete/",
            "/user/resetPassword/",
            "/user/status",
            "/user/role/list",
            "/user/role/status"
    );


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法，直接放行(避免拦截其他请求)
            return true;
        }

        //1、从请求头中获取令牌,并判断身份
        String token = request.getHeader(jwtProperties.getTokenName());

        //2、校验令牌
        try {
            Claims claims = new DefaultClaims();
            // 先解析获取角色信息
            claims = JwtUtil.parseJWT(jwtProperties.getSecretKey(), token); // 先尝试用管理员密钥解析

            String userId = String.valueOf(claims.get("id").toString());

            //将令牌中的id存储到线程局部变量中
            UserContext.setUser(userId);

            String role = String.valueOf(claims.get("role"));

            // 检查用户角色和请求路径
            if ("user".equals(role)) {
                String requestUri = request.getRequestURI();
                for (String path : ROLE_MANAGEMENT_PATHS) {
                    if (requestUri.startsWith(path)) {
                        log.info("用户角色为 user，禁止访问角色管理模块接口: {}", requestUri);
                        response.setStatus(403); // 返回 403 状态码，表示禁止访问
                        return false;
                    }
                }
            }

            //3、通过，放行
            log.info("Token通过");
            return true;
        } catch (Exception ex) {    //在解析JWT令牌的过程中发生异常（例如，令牌无效、签名错误等），则捕获异常
            //4、不通过，响应401状态码
            log.info("Token未通过");
            response.setStatus(401);
            return false;
        }

    }

}

